use std::sync::mpsc::Sender;

use egui::{style::Spacing, Frame, Layout, Ui, Vec2};
use serde::{Deserialize, Serialize};
use thunderdome::Arena;


use QcCore::ecs::graph::Graph;
use QcMacros::Control;

use QcTools::message::messageSender::MessageSender;
use QcWindowing::{CursorIcon, Window};

use crate::{
    core::{context::UiContext, layer::Layer},
    message::UiMessage,
};

use super::{Canvas, ToUi, UiNode, UiNodeTrait};

#[derive(Control, Serialize, Deserialize, Debug)]
pub struct Grid {
    pub widget: Widget,
    pub columns: i32,
    pub spacing: Vec2,
}

#[typetag::serde]
impl UiNodeTrait for Grid {
    fn renderFrame(&self, ctx: &mut UiContext) -> egui::Frame {
        let frame = Frame::none()
            .fill(self.background)
            .inner_margin(self.padding)
            .outer_margin(self.margin);

        frame
    }

    fn renderInner(&mut self, ctx: &mut UiContext) {
        let UiContext {
            ui,
            sender,
            canvas_ptr,
        } = ctx;
        ui.scope(|ui| {
            if self.width != 0.0 && self.height != 0.0 {
                ui.set_width(self.width);
                ui.set_height(self.height);
            }

            let canvas = unsafe { &mut **canvas_ptr };

            let res = egui::Grid::new(&self.name)
                .spacing(self.spacing)
                .show(ui, |ui| {
                    for (num, index) in self.children.iter().enumerate() {
                        let node = &mut canvas[*index];
                        node.render(&mut UiContext::new(ui, sender).with_canvas_ptr(*canvas_ptr));

                        if num as i32 % self.columns == 0 {
                            ui.end_row();
                        }
                    }
                });
        });
    }
}

impl Default for Grid {
    fn default() -> Self {
        Self {
            widget: Widget::default()
                .with_name("Grid")
                .with_width(200.)
                .with_height(200.),
            columns: 1,
            spacing: Default::default(),
        }
    }
}

impl Grid {
    pub fn new(widget: Widget) -> Self {
        Self {
            widget,
            columns: 1,
            ..Default::default()
        }
    }

    pub fn with_spacing(mut self, spacing: Vec2) -> Self {
        self.spacing = spacing;
        self
    }

    pub fn with_columns(mut self, columns: i32) -> Self {
        self.columns = columns;
        self
    }

    pub fn with_children(mut self, children: Vec<Index>, canvas: &mut Canvas) -> Self {
        for index in children {
            self.children.push(index);

            canvas[index].get_widget_mut().set_layer(Layer::Grid);
        }
        self
    }

    pub fn build(self, canvas: &mut Canvas) -> Index {
        let panel = canvas.add_child(UiNode::Grid(self));

        let children = &canvas[panel].get_widget().children.clone();

        for index in children {
            let widget = canvas[*index].get_widget_mut();

            widget.set_parent(Some(panel));
        }

        panel
    }
}

impl ToUi for Grid {
    fn toUi(self) -> UiNode {
        UiNode::Grid(self)
    }
}
